home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2009 June / PersonalComputerWorld-June2009-CoverdiscCD.iso / Software / Freeware / Firebug 1.3.3 / firebug-1.3.3-fx.xpi / content / firebug / errors.js < prev    next >
Encoding:
JavaScript  |  2009-02-19  |  13.3 KB  |  466 lines

  1. /* See license.txt for terms of usage */
  2.  
  3. FBL.ns(function() { with (FBL) {
  4.  
  5. // ************************************************************************************************
  6. // Constants
  7.  
  8. const Cc = Components.classes;
  9. const Ci = Components.interfaces;
  10. const nsIScriptError = Ci.nsIScriptError;
  11.  
  12. const WARNING_FLAG = nsIScriptError.warningFlag;
  13.  
  14. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  15.  
  16. const urlRe = new RegExp("([^:]*):(//)?([^/]*)");
  17. const reUncaught = /uncaught exception/;
  18. const reException = /uncaught exception:\s\[Exception...\s\"([^\"]*)\".*nsresult:.*\(([^\)]*)\).*location:\s\"([^\s]*)\sLine:\s(\d*)\"/;
  19. const statusBar = $("fbStatusBar");
  20. const statusText = $("fbStatusText");
  21.  
  22. const pointlessErrors =
  23. {
  24.     "uncaught exception: Permission denied to call method Location.toString": 1,
  25.     "uncaught exception: Permission denied to get property Window.writeDebug": 1,
  26.     "uncaught exception: Permission denied to get property XULElement.accessKey": 1,
  27.     "this.docShell has no properties": 1,
  28.     "aDocShell.QueryInterface(Components.interfaces.nsIWebNavigation).currentURI has no properties": 1,
  29.     "Deprecated property window.title used. Please use document.title instead.": 1,
  30.     "Key event not available on GTK2:": 1
  31. };
  32.  
  33. // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  34.  
  35. const fbs = Cc["@joehewitt.com/firebug;1"].getService().wrappedJSObject;
  36. const consoleService = CCSV("@mozilla.org/consoleservice;1", "nsIConsoleService");
  37.  
  38. // ************************************************************************************************
  39.  
  40. var Errors = Firebug.Errors = extend(Firebug.Module,
  41. {
  42.     clear: function(context)
  43.     {
  44.         this.setCount(context, 0)
  45.     },
  46.  
  47.     increaseCount: function(context)
  48.     {
  49.         this.setCount(context, context.errorCount + 1)
  50.     },
  51.  
  52.     setCount: function(context, count)
  53.     {
  54.         context.errorCount = count;
  55.  
  56.         if (context == FirebugContext)
  57.             this.showCount(context.errorCount);
  58.     },
  59.  
  60.     showMessageOnStatusBar: function(error)
  61.     {
  62.         if (statusText && statusBar && Firebug.breakOnErrors && error.message &&  !(error.flags & WARNING_FLAG))  // sometimes statusText is undefined..how?
  63.         {
  64.             statusText.setAttribute("value", error.message);
  65.             statusBar.setAttribute("errors", "true");
  66.         }
  67.     },
  68.  
  69.     showCount: function(errorCount)
  70.     {
  71.         if (!statusBar)
  72.             return;
  73.  
  74.         if (errorCount)
  75.         {
  76.             if (Firebug.showErrorCount)
  77.             {
  78.                 var errorLabel = errorCount > 1
  79.                     ? $STRF("ErrorsCount", [errorCount])
  80.                     : $STRF("ErrorCount", [errorCount]);
  81.  
  82.                 statusText.setAttribute("value", errorLabel);
  83.             }
  84.  
  85.             statusBar.setAttribute("errors", "true");
  86.         }
  87.         else
  88.         {
  89.             statusText.setAttribute("value", "");
  90.             statusBar.removeAttribute("errors");
  91.         }
  92.     },
  93.  
  94.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  95.     // Called by Console
  96.  
  97.     startObserving: function()
  98.     {
  99.         var errorsOn = $('fbStatusIcon').getAttribute("errors"); // signal user and be a marker.
  100.         if (!errorsOn) // need to be safe to multiple calls
  101.         {
  102.             consoleService.registerListener(this);
  103.             $('fbStatusIcon').setAttribute("errors", "on");
  104.         }
  105.     },
  106.  
  107.     stopObserving: function()
  108.     {
  109.         var errorsOn = $('fbStatusIcon').getAttribute("errors");
  110.         if (errorsOn)  // need to be safe to multiple calls
  111.         {
  112.             try
  113.             {
  114.                 consoleService.unregisterListener(this);
  115.                 $('fbStatusIcon').removeAttribute("errors");
  116.             }
  117.             catch (e)
  118.             {
  119.             }
  120.         }
  121.     },
  122.  
  123.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  124.     // extends consoleListener
  125.  
  126.     observe: function(object)
  127.     {
  128.         try
  129.         {
  130.             if (!FBTrace)
  131.                 return;
  132.         }
  133.         catch(exc)
  134.         {
  135.             return;
  136.         }
  137.         
  138.         try
  139.         {
  140.             var context = null;
  141.             if (FirebugContext)
  142.                 context = FirebugContext;
  143.  
  144.             if (object instanceof nsIScriptError)
  145.             {
  146.                 var isWarning = object.flags & WARNING_FLAG;  // This cannot be pulled in front of the instanceof
  147.                 context = this.logScriptError(context, object, isWarning)
  148.                 if(!context)
  149.                     return;
  150.             }
  151.             else
  152.             {
  153.                 var isWarning = object.flags & WARNING_FLAG;
  154.                 if (Firebug.showChromeMessages)
  155.                 {
  156.                     if (lessTalkMoreAction(context, object, isWarning))
  157.                         return;
  158.                     if (context) // Must be an nsIConsoleMessage
  159.                         Firebug.Console.log(object.message, context, "consoleMessage", FirebugReps.Text);
  160.                     else
  161.                     {
  162.                         return;
  163.                     }
  164.                 }
  165.                 else
  166.                 {
  167.                     return;
  168.                 }
  169.             }
  170.         }
  171.         catch (exc)
  172.         {
  173.             // Errors prior to console init will come out here, eg error message from Firefox startup jjb.
  174.         }
  175.     },
  176.  
  177.     logScriptError: function(context, object, isWarning)
  178.     {
  179.         var category = getBaseCategory(object.category);
  180.         var isJSError = category == "js" && !isWarning;
  181.  
  182.         var errorContext = getErrorContext(object);
  183.         if (errorContext)
  184.             context = errorContext;
  185.  
  186.         if (Firebug.showStackTrace && Firebug.errorStackTrace)
  187.         {
  188.             var trace = Firebug.errorStackTrace;
  189.             trace = this.correctLineNumbersWithStack(trace, object) ? trace : null;
  190.         }
  191.         else if (checkForUncaughtException(context, object))
  192.         {
  193.             context = getExceptionContext(context);
  194.             correctLineNumbersOnExceptions(context, object);
  195.         }
  196.  
  197.         if (lessTalkMoreAction(context, object, isWarning))
  198.             return null;
  199.  
  200.         Firebug.errorStackTrace = null;  // clear global: either we copied it or we don't use it.
  201.         context.thrownStackTrace = null;
  202.  
  203.         if (!isWarning)
  204.             this.increaseCount(context);
  205.  
  206.         var error = new ErrorMessage(object.errorMessage, object.sourceName,
  207.             object.lineNumber, object.sourceLine, category, context, trace);  // the sourceLine will cause the source to be loaded.
  208.  
  209.         var className = isWarning ? "warningMessage" : "errorMessage";
  210.  
  211.         if (context)
  212.         {
  213.              // then report later to avoid loading sourceS
  214.             context.throttle(Firebug.Console.log, Firebug.Console, [error, context,  className, false, true], true);
  215.         }
  216.         else
  217.         {
  218.             Firebug.Console.log(error, context,  className);
  219.         }
  220.         return context;
  221.     },
  222.  
  223.     correctLineNumbersWithStack: function(trace, object)
  224.     {
  225.         var stack_frame = trace.frames[0];
  226.         if (stack_frame)
  227.         {
  228.             sourceName = stack_frame.href;
  229.             lineNumber = stack_frame.lineNo;
  230.             // XXXjjb Seems to change the message seen in Firefox Error Console
  231.             var correctedError = object.init(object.errorMessage, sourceName, object.sourceLine,lineNumber, object.columnNumber, object.flags, object.category);
  232.             return true;
  233.         }
  234.         return false;
  235.     },
  236.     
  237.     // * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * *
  238.     // extends Module
  239.  
  240.     initContext: function(context)
  241.     {
  242.         context.errorCount = 0;
  243.     },
  244.  
  245.     showContext: function(browser, context)
  246.     {
  247.         this.showCount(context ? context.errorCount : 0);
  248.     }
  249. });
  250.  
  251. // ************************************************************************************************
  252. // Local Helpers
  253.  
  254. const categoryMap =
  255. {
  256.     "javascript": "js",
  257.     "JavaScript": "js",
  258.     "DOM": "js",
  259.     "Events": "js",
  260.     "CSS": "css",
  261.     "XML": "xml",
  262.     "malformed-xml": "xml"
  263. };
  264.  
  265. function getBaseCategory(categories)
  266. {
  267.     var categoryList = categories.split(" ");
  268.     for (var i = 0 ; i < categoryList.length; ++i)
  269.     {
  270.         var category = categoryList[i];
  271.         if ( categoryMap.hasOwnProperty(category) )
  272.             return categoryMap[category];
  273.     }
  274. }
  275.  
  276. function isShownCategory(url, category, isWarning)
  277. {
  278.     var m = urlRe.exec(url);
  279.     var errorScheme = m ? m[1] : "";
  280.     if (errorScheme == "javascript")
  281.         return true;
  282.  
  283.     var isChrome = false;
  284.  
  285.     if (!category)
  286.         return Firebug.showChromeErrors;
  287.  
  288.     var categories = category.split(" ");
  289.     for (var i = 0 ; i < categories.length; ++i)
  290.     {
  291.         var category = categories[i];
  292.         if (category == "CSS" && !Firebug.showCSSErrors)
  293.             return false;
  294.         else if ((category == "XML" || category == "malformed-xml" ) && !Firebug.showXMLErrors)
  295.             return false;
  296.         else if ((category == "javascript" || category == "JavaScript" || category == "DOM")
  297.                     && !isWarning && !Firebug.showJSErrors)
  298.             return false;
  299.         else if ((category == "javascript" || category == "JavaScript" || category == "DOM")
  300.                     && isWarning && !Firebug.showJSWarnings)
  301.             return false;
  302.         else if (errorScheme == "chrome" || category == "XUL" || category == "chrome" || category == "XBL"
  303.                 || category == "component")
  304.             isChrome = true;
  305.     }
  306.  
  307.     if ((isChrome && !Firebug.showChromeErrors))
  308.         return false;
  309.  
  310.     return true;
  311. }
  312.  
  313. function domainFilter(url)  // never called?
  314. {
  315.     if (Firebug.showExternalErrors)
  316.         return true;
  317.  
  318.     var browserWin = document.getElementById("content").contentWindow;
  319.  
  320.     var m = urlRe.exec(browserWin.location.href);
  321.     if (!m)
  322.         return false;
  323.  
  324.     var browserDomain = m[3];
  325.  
  326.     m = urlRe.exec(url);
  327.     if (!m)
  328.         return false;
  329.  
  330.     var errorScheme = m[1];
  331.     var errorDomain = m[3];
  332.  
  333.     return errorScheme == "javascript"
  334.         || errorScheme == "chrome"
  335.         || errorDomain == browserDomain;
  336. }
  337.  
  338. function lessTalkMoreAction(context, object, isWarning)
  339. {
  340.     if (!context || !isShownCategory(object.sourceName, object.category, isWarning))
  341.     {
  342.         return true;
  343.     }
  344.  
  345.     var enabled = Firebug.Console.isEnabled(context);
  346.     if (!enabled) {
  347.         FBTrace.sysout("errors.observe not enabled for context "+(context.window?context.window.location:"no window")+"\n");
  348.         return true;
  349.     }
  350.  
  351.     var incoming_message = object.errorMessage;  // nsIScriptError
  352.     if (!incoming_message)                       // nsIConsoleMessage
  353.         incoming_message = object.message;
  354.  
  355.  
  356.     for (var msg in pointlessErrors)
  357.     {
  358.  
  359.         if( msg.charAt(0) == incoming_message.charAt(0) )
  360.         {
  361.             if (incoming_message.indexOf(msg) == 0)
  362.             {
  363.                 return true;
  364.             }
  365.         }
  366.     }
  367.  
  368.     var msgId = [incoming_message, object.sourceName, object.lineNumber].join("/");
  369.     if (context.errorMap && msgId in context.errorMap)
  370.     {
  371.         context.errorMap[msgId] += 1;
  372.         return true;
  373.     }
  374.  
  375.     if (!context.errorMap)
  376.         context.errorMap = {};
  377.  
  378.     context.errorMap[msgId] = 1;
  379.  
  380.     return false;
  381. }
  382.  
  383. function getErrorContext(object)
  384. {
  385.     var errorContext = null;
  386.  
  387.     var url = object.sourceName;
  388.  
  389.     TabWatcher.iterateContexts(
  390.         function findContextByURL(context)
  391.         {
  392.             if (!context.window || !context.window.location)
  393.                 return;
  394.  
  395.             if (context.window.location.toString() == url)
  396.                 return errorContext = context;
  397.             else
  398.             {
  399.                 if (context.sourceFileMap && context.sourceFileMap[url])
  400.                     return errorContext = context;
  401.             }
  402.         }
  403.     );
  404.  
  405.     return errorContext; // we looked everywhere...
  406. }
  407.  
  408. function checkForUncaughtException(context, object)
  409. {
  410.     if (object.flags & object.exceptionFlag)
  411.     {
  412.         if (reUncaught.test(object.errorMessage))
  413.         {
  414.             if (context.thrownStackTrace)
  415.             {
  416.                 Firebug.errorStackTrace = context.thrownStackTrace;
  417.             }
  418.             else
  419.             {
  420.             }
  421.             return true;
  422.         }
  423.         else
  424.         {
  425.         }
  426.     }
  427.     return false;
  428. }
  429.  
  430. function getExceptionContext(context)
  431. {
  432.     var errorWin = fbs.lastErrorWindow;  // not available unless Script panel is enabled.
  433.     if (errorWin)
  434.     {
  435.         var errorContext = TabWatcher.getContextByWindow(errorWin);
  436.         return errorContext;
  437.     }
  438.     return context;
  439. }
  440.  
  441. function correctLineNumbersOnExceptions(context, object)
  442. {
  443.     var m = reException.exec(object.errorMessage);
  444.     if (m)
  445.     {
  446.         var exception = m[1];
  447.         if (exception)
  448.             errorMessage = "uncaught exception: "+exception;
  449.         var nsresult = m[2];
  450.         if (nsresult)
  451.             errorMessage += " ("+nsresult+")";
  452.         sourceName = m[3];
  453.         lineNumber = m[4];
  454.  
  455.         var correctedError = object.init(errorMessage, sourceName, object.sourceLine, lineNumber, object.columnNumber, object.flags, object.category);
  456.     }
  457. }
  458.  
  459. // ************************************************************************************************
  460.  
  461. Firebug.registerModule(Errors);
  462.  
  463. // ************************************************************************************************
  464.  
  465. }});
  466.